From 35325ea11ad97186281a45bf056c4939cc651a28 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Fri, 7 Aug 2020 12:25:06 -0700 Subject: [PATCH] linedisplaycache: improve invalidation with y_range When we invalidate a y_range using the common pattern of y==0 and old_height==new_height, we are generally invalidating the entire buffer. This short-circuits that case to just invalidate the buffer in a faster and more complete form. The problem here appears to be that we can't always calculate the ranges properly to invalidate because validation has not run far enough. --- gtk/gtktextlayout.c | 4 ++-- gtk/gtktextlinedisplaycache.c | 10 ++++++++-- gtk/gtktextlinedisplaycacheprivate.h | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index 78439277bf..3e77b52f6c 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -656,7 +656,7 @@ gtk_text_layout_changed (GtkTextLayout *layout, int new_height) { GtkTextLayoutPrivate *priv = GTK_TEXT_LAYOUT_GET_PRIVATE (layout); - gtk_text_line_display_cache_invalidate_y_range (priv->cache, layout, y, old_height, FALSE); + gtk_text_line_display_cache_invalidate_y_range (priv->cache, layout, y, old_height, new_height, FALSE); gtk_text_layout_emit_changed (layout, y, old_height, new_height); } @@ -667,7 +667,7 @@ gtk_text_layout_cursors_changed (GtkTextLayout *layout, int new_height) { GtkTextLayoutPrivate *priv = GTK_TEXT_LAYOUT_GET_PRIVATE (layout); - gtk_text_line_display_cache_invalidate_y_range (priv->cache, layout, y, old_height, TRUE); + gtk_text_line_display_cache_invalidate_y_range (priv->cache, layout, y, old_height, new_height, TRUE); gtk_text_layout_emit_changed (layout, y, old_height, new_height); } diff --git a/gtk/gtktextlinedisplaycache.c b/gtk/gtktextlinedisplaycache.c index 91ce0d98e4..27f05ad660 100644 --- a/gtk/gtktextlinedisplaycache.c +++ b/gtk/gtktextlinedisplaycache.c @@ -642,7 +642,8 @@ find_iter_at_at_y (GtkTextLineDisplayCache *cache, * gtk_text_line_display_cache_invalidate_y_range: * @cache: a GtkTextLineDisplayCache * @y: the starting Y position - * @old_height: the height to invalidate + * @old_height: the old height of the range + * @new_height: the new height of the range * @cursors_only: if only cursors should be invalidated * * Remove all GtkTextLineDisplay that fall into the range starting @@ -653,6 +654,7 @@ gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache, GtkTextLayout *layout, int y, int old_height, + int new_height, gboolean cursors_only) { GSequenceIter *iter; @@ -663,7 +665,11 @@ gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache, STAT_INC (cache->inval_by_y_range); - if (y < 0) + /* A common pattern is to invalidate the whole buffer using y==0 and + * old_height==new_height. So special case that instead of walking through + * each display item one at a time. + */ + if (y < 0 || (y == 0 && old_height == new_height)) { gtk_text_line_display_cache_invalidate (cache); return; diff --git a/gtk/gtktextlinedisplaycacheprivate.h b/gtk/gtktextlinedisplaycacheprivate.h index ffbe67bd42..3102109248 100644 --- a/gtk/gtktextlinedisplaycacheprivate.h +++ b/gtk/gtktextlinedisplaycacheprivate.h @@ -51,7 +51,8 @@ void gtk_text_line_display_cache_invalidate_range (GtkText void gtk_text_line_display_cache_invalidate_y_range (GtkTextLineDisplayCache *cache, GtkTextLayout *layout, int y, - int height, + int old_height, + int new_height, gboolean cursors_only); void gtk_text_line_display_cache_set_mru_size (GtkTextLineDisplayCache *cache, guint mru_size); -- 2.30.2